home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 359_11 / patch5.000 / GO32_VALLOC.C < prev    next >
C/C++ Source or Header  |  1991-09-11  |  6KB  |  293 lines

  1. /* This is file VALLOC.C */
  2. /*
  3. ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
  16. /* History:126,1 */
  17.  
  18. #include <stdio.h>
  19. #include <dos.h>
  20.  
  21. #include "build.h"
  22. #include "types.h"
  23. #include "valloc.h"
  24. #include "xms.h"
  25. #include "mono.h"
  26. #include "vcpi.h"
  27.  
  28. #define VA_FREE    0
  29. #define VA_USED    1
  30.  
  31. #define    DOS_PAGE 256        /*  1MB / 4KB = 256 Pages  */
  32.  
  33. int valloc_initted = 0;
  34. static word8 map[4096];
  35. word16 mem_avail, mem_used;
  36. static word16 left_lo, left_hi;
  37.  
  38. static unsigned pn_lo_first, pn_lo_last, pn_hi_first, pn_hi_last;
  39. static unsigned vcpi_flush_ok = 0;
  40.  
  41. extern int debug_mode;
  42. extern word16 vcpi_installed;    /*  VCPI Installed set this not Zero  */
  43.  
  44. #if TOPLINEINFO
  45. valloc_update_status()
  46. {
  47.   char buf[20];
  48.   int i;
  49. #if 0
  50.   if (!debug_mode)
  51.     return;
  52. #endif
  53.   if (!valloc_initted)
  54.     return;
  55.   sprintf(buf, "%5dk", mem_avail);
  56.   for (i=0; i<6; i++)
  57.     poke(screen_seg, (i+70)*2, buf[i] | 0x0a00);
  58.   sprintf(buf, "%5dk", mem_used);
  59.   for (i=0; i<6; i++)
  60.     poke(screen_seg, (i+62)*2, buf[i] | 0x0a00);
  61. }
  62. #endif
  63.  
  64. static void vset(unsigned i, int b)
  65. {
  66.   unsigned o, m;
  67.   o = i>>3;
  68.   m = 1<<(i&7);
  69.   if (b)
  70.   {
  71.     if (!(map[o] & m))
  72.     {
  73. #if TOPLINEINFO
  74.       mem_avail -= 4;
  75.       mem_used += 4;
  76.       valloc_update_status();
  77. #endif
  78.       map[o] |= m;
  79.     }
  80.   }
  81.   else
  82.   {
  83.     if (map[o] & m)
  84.     {
  85. #if TOPLINEINFO
  86.       mem_avail += 4;
  87.       mem_used -= 4;
  88.       valloc_update_status();
  89. #endif
  90.       map[o] &= ~m;
  91.     }
  92.   }
  93. }
  94.  
  95. static int vtest(unsigned i)
  96. {
  97.   unsigned o, m;
  98.   o = i>>3;
  99.   m = 1<<(i&7);
  100.   return map[o] & m;
  101. }
  102.  
  103.  
  104. emb_handle_t emb_handle=-1;
  105.  
  106. void
  107. xms_free(void) {
  108.     if(use_xms && emb_handle != -1) {
  109.         xms_unlock_emb(emb_handle);
  110.         xms_emb_free(emb_handle);
  111. #if DEBUGGER
  112.     printf("XMS memory freed\n");
  113. #endif
  114.     }
  115. }
  116.  
  117. void
  118. xms_alloc_init(void) {
  119.     xms_extended_info *x = xms_query_extended_memory();
  120.     emb_off_t linear_base;
  121.     emb_size_K_t emb_size;
  122. #if DEBUGGER
  123.     printf("XMS driver detected\n");
  124. #endif
  125.     emb_size = x->max_free_block;
  126.     emb_handle = xms_emb_allocate(emb_size);
  127.     linear_base = xms_lock_emb(emb_handle);
  128.     pn_hi_first = (linear_base + 4095)/4096;
  129.     pn_hi_last = pn_hi_first + emb_size / 4 - 1;
  130. }
  131.  
  132.  
  133. static valloc_init()
  134. {
  135.   unsigned char far *vdisk;
  136.   int has_vdisk=1;
  137.   unsigned long vdisk_top;
  138.   unsigned los, i, lol;
  139.   struct REGPACK r;
  140.   
  141.   if (vcpi_installed)
  142.     {
  143.     pn_hi_first = 32767;
  144.     pn_hi_last  = DOS_PAGE;
  145.     }
  146.   else if(use_xms) {
  147.       xms_alloc_init();    /*  Try XMS allocation  */
  148.       }
  149.   else {
  150.     /*
  151.     ** int 15/vdisk memory allocation
  152.     */
  153.     r.r_ax = 0x8800;    /* get extended memory size */
  154.     intr(0x15, &r);
  155.     pn_hi_last = r.r_ax / 4 + 255;
  156.  
  157.     /* get ivec 19h, seg only */
  158.     vdisk = (char far *)(*(long far *)0x64L & 0xFFFF0000L);
  159.     for (i=0; i<5; i++)
  160.       if (vdisk[i+18] != "VDISK"[i])
  161.         has_vdisk = 0;
  162.     if (has_vdisk)
  163.     {
  164.       vdisk_top = vdisk[46] * 65536L + vdisk[45] * 256 + vdisk[44];
  165.       pn_hi_first = (vdisk_top + 4095) / 4096;
  166.     }
  167.     else
  168.       pn_hi_first = 256;
  169.   }
  170.  
  171.   r.r_ax= 0x4800;    /* get real memory size */
  172.   r.r_bx = 0xffff;
  173.   intr(0x21, &r);    /* lol == size of largest free memory block */
  174.   lol = r.r_bx;
  175.   r.r_ax = 0x4800;
  176.   intr(0x21, &r);    /* get the block */
  177.   pn_lo_first = (r.r_ax+0xFF) >> 8;    /* lowest real mem 4K block */
  178.   pn_lo_last = (r.r_ax+lol-1) >> 8; /* highest real mem 4K block */
  179.  
  180.   r.r_es = r.r_ax;    /* free the block just allocated */
  181.   r.r_ax = 0x4900;    /* because Turbo Debugger won't if we don't */
  182.   intr(0x21, &r);
  183.  
  184.   mem_avail = 0;
  185.   for ( i=0; i<DOS_PAGE/8; i++)
  186.     map[i] = 0xff;    /* DOS Area  */
  187.   for (    ; i<4096; i++)
  188.     map[i] = (vcpi_installed)? 0x00:0xff;    /* Extened Memory Area  */
  189.  
  190.   for (i=pn_lo_first; i<=pn_lo_last; i++)
  191.     vset(i, VA_FREE);
  192.   for (i=pn_hi_first; i<=pn_hi_last; i++)
  193.     vset(i, VA_FREE);
  194.   vcpi_flush_ok = 1;
  195.  
  196.   mem_used = 0;
  197.   left_lo  = (pn_lo_last - pn_lo_first + 1)*4;
  198.   left_hi  = (vcpi_installed)? vcpi_capacity()*4:(pn_hi_last-pn_hi_first+1)*4;
  199.   if (vcpi_installed)
  200.     mem_avail = left_lo + left_hi;
  201.  
  202. /*  mem_avail = (pn_lo_last-pn_lo_first+1)*4 + (pn_hi_last-pn_hi_first+1)*4; */
  203. #if DEBUGGER
  204.   if (debug_mode)
  205.     printf("%d Kb conventional, %d Kb extended - %d Kb total RAM available\n",
  206.       left_lo,left_hi,mem_avail);
  207. #endif
  208.  
  209. #if TOPLINEINFO
  210.   valloc_update_status();
  211. #endif
  212.   valloc_initted = 1;
  213. }
  214.  
  215. unsigned valloc(where)
  216. {
  217.   unsigned pn;
  218.   if (!valloc_initted)
  219.     valloc_init();
  220.   switch (where)
  221.   {
  222.     case VA_640:
  223.       more_640:
  224.       for (pn=pn_lo_first; pn<=pn_lo_last; pn++)
  225.         if (vtest(pn) == VA_FREE)
  226.         {
  227.           left_lo -= 4;
  228.           vset(pn, VA_USED);
  229.           return pn;
  230.         }
  231.       page_out(where);
  232.       goto more_640;
  233.     case VA_1M:
  234.       more_1m:
  235.       if (vcpi_installed)
  236.     {
  237.     if (pn = vcpi_alloc())
  238.       {
  239.       left_hi -= 4;
  240.       if (pn < pn_hi_first)
  241.         pn_hi_first = pn;
  242.       if (pn > pn_hi_last)
  243.         pn_hi_last  = pn;
  244.       vset(pn,VA_USED);
  245.       return pn;
  246.       }
  247.     }
  248.       else
  249.     {
  250.         for (pn=pn_hi_first; pn<=pn_hi_last; pn++)
  251.           if (vtest(pn) == VA_FREE)
  252.             {
  253.             left_hi -= 4;
  254.             vset(pn, VA_USED);
  255.             return pn;
  256.             }
  257.     }
  258.  
  259.       for (pn=pn_lo_first; pn<=pn_lo_last; pn++)
  260.         if (vtest(pn) == VA_FREE)
  261.         {
  262.           left_lo -= 4;
  263.           vset(pn, VA_USED);
  264.           return pn;
  265.         }
  266.       page_out(where);
  267.       goto more_1m;
  268.   }
  269.   return 0;
  270. }
  271.  
  272. void vfree(unsigned pn)
  273. {
  274.   if ((vcpi_installed)&&(pn >= DOS_PAGE))
  275.     vcpi_free(pn);
  276.   vset(pn, VA_FREE);
  277. }
  278.  
  279. void vcpi_flush(void)
  280. {
  281.   word16 pn;
  282.  
  283.   if (!vcpi_flush_ok)
  284.     return;            /*  Not Initaialized Map[]  */
  285.   for(pn = pn_hi_first; pn <= pn_hi_last; pn++)
  286.     if (vtest(pn))
  287.       vcpi_free(pn);
  288.  
  289. #if DEBUGGER
  290.   printf("VCPI memory freed\n");
  291. #endif
  292. }
  293.